package com.avecsys.quotemanager.dao.supplier;

import java.sql.SQLException;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;

import com.avecsys.quotemanager.dao.common.BaseDAOImpl;
import com.avecsys.quotemanager.dao.common.EnumDBRecordStatus;
import com.avecsys.quotemanager.dao.common.EnumTransactionStatus;
import com.avecsys.quotemanager.exception.DAOException;
import com.avecsys.quotemanager.pojos.BuyerUsersPojo;
import com.avecsys.quotemanager.pojos.SupplierMasterPojo;
import com.avecsys.quotemanager.pojos.SupplierUsersPojo;
import com.avecsys.quotemanager.utils.TransactionStatus;

/**
 * @author Sam Sundar K Represents the implementaion for the DAO - SUpplier
 *         master
 * 
 */
public class SupplierMasterDAOImpl extends BaseDAOImpl implements
		SupplierMasterDAO {

	private static final Log log = LogFactory
			.getLog(SupplierMasterDAOImpl.class);

	public TransactionStatus saveSupplier(
			final SupplierMasterPojo supplierMasterPojo) throws DAOException {
		TransactionStatus transactionStatus = new TransactionStatus(
				EnumTransactionStatus.SAVE_SUCESS.ordinal());
		try {
			getHibernateTemplate().execute(new HibernateCallback<Object>() {
				@Override
				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
					// 1. Save Company Information
					session.save(supplierMasterPojo.getCompanyMasterPojo());
					// 2. Save Supplier Master Information
					session.save(supplierMasterPojo);
					// 3. Save Default Administrator Supplier User Information
					for (SupplierUsersPojo supplierUsersPojo : supplierMasterPojo
							.getSupplierUsers()) {
						session.save(supplierUsersPojo.getUserMasterPojo());
						session.save(supplierUsersPojo);
					}
					return supplierMasterPojo;
				}
			});
		} catch (Exception e) {
			log.error(e);
			transactionStatus.setStatus(EnumTransactionStatus.SAVE_FAIL
					.ordinal());
			throw new DAOException(e);
		}
		return transactionStatus;

	}

	public TransactionStatus updateSupplier(
			final SupplierMasterPojo supplierMasterPojo) throws DAOException {
		TransactionStatus transactionStatus = new TransactionStatus(
				EnumTransactionStatus.UPDATE_SUCCESS.ordinal());
		try {
			getHibernateTemplate().execute(new HibernateCallback<Object>() {
				@Override
				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
					// 1. Save Company Information
					session.update(supplierMasterPojo.getCompanyMasterPojo());
					// 2. Save Supplier Master Information
					session.update(supplierMasterPojo);
					// 3. Save or Update Default Administrator Supplier User
					// Information
					for (SupplierUsersPojo supplierUsersPojo : supplierMasterPojo
							.getSupplierUsers()) {
						session.saveOrUpdate(supplierUsersPojo);
					}
					return supplierMasterPojo;
				}
			});
		} catch (Exception e) {
			log.error(e);
			transactionStatus.setStatus(EnumTransactionStatus.UPDATE_FAIL
					.ordinal());
			throw new DAOException(e);
		}
		return transactionStatus;
	}

	public TransactionStatus deleteSupplier(
			final SupplierMasterPojo supplierMasterPojo) throws DAOException {
		TransactionStatus transactionStatus = new TransactionStatus(
				EnumTransactionStatus.DELETE_SUCCESS.ordinal());
		try {
			getHibernateTemplate().execute(new HibernateCallback<Object>() {
				@Override
				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
					// 1. Mark Supplier as deleted
					supplierMasterPojo.setStatus(EnumDBRecordStatus.DELETED
							.status());
					session.update(supplierMasterPojo);
					// 3. Save or Update Default Administrator Supplier User
					// Information
					for (SupplierUsersPojo supplierUsersPojo : supplierMasterPojo
							.getSupplierUsers()) {
						supplierUsersPojo.setStatus(EnumDBRecordStatus.DELETED
								.status());
						session.update(supplierUsersPojo);
						// If Supplier User is not associated as buyer for
						// another
						// supplier then mark the userMasterPojo status as
						// deleted
						Set<BuyerUsersPojo> buyerUsersPojoSet = supplierUsersPojo
								.getUserMasterPojo().getBuyerUsersPojo();
						if (buyerUsersPojoSet != null
								&& buyerUsersPojoSet.size() == 0) {
							supplierUsersPojo.getUserMasterPojo().setStatus(
									EnumDBRecordStatus.DELETED.status());
							session.update(supplierUsersPojo
									.getUserMasterPojo());
						} else {
							log.info("The supplier user "
									+ supplierUsersPojo.getUserMasterPojo()
											.getEmail()
									+ " is associated as Buyer to another supplier. So not marking as deleted in supplier user delete operation.");
						}
					}
					return supplierMasterPojo;
				}
			});
		} catch (Exception e) {
			log.error(e);
			transactionStatus.setStatus(EnumTransactionStatus.DELETE_FAIL
					.ordinal());
			throw new DAOException(e);
		}
		return transactionStatus;
	}
}
